package com.itlong.cloud.commons.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.DTO.app.AppElevatorAuthDTO;
import com.itlong.cloud.POJO.DTO.common.IotPubMessageDTO;
import com.itlong.cloud.POJO.DTO.property.CloudIntercomChangeLogGetDTO;
import com.itlong.cloud.POJO.PO.*;
import com.itlong.cloud.POJO.VO.app.AppElevatorAuthVO;
import com.itlong.cloud.POJO.VO.app.AppElevatorInfoVO;
import com.itlong.cloud.POJO.VO.common.CloudEntranceVO;
import com.itlong.cloud.POJO.VO.common.ProjectIotInfo;
import com.itlong.cloud.POJO.VO.operate.OperateUpdateDetailVO;
import com.itlong.cloud.POJO.VO.property.*;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.app.dao.IAppDeviceDao;
import com.itlong.cloud.commons.dao.ICloudElevatorDao;
import com.itlong.cloud.commons.dao.ICloudEntranceDao;
import com.itlong.cloud.commons.service.ICloudEntranceService;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.*;
import com.itlong.cloud.operate.dao.IOperatePackageDao;
import com.itlong.cloud.property.dao.ICloudIntercomDeviceServiceDao;
import com.itlong.cloud.property.dao.IDeviceEntranceInfoDao;
import com.itlong.cloud.enumerate.DeviceIotEnum;
import com.itlong.cloud.enumerate.IotCloudCtrlInstructEnum;
import com.itlong.cloud.enumerate.SystemTypeEnum;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.encrypt.UserTokenUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <desc>
 *      云门禁业务处理接口实现类
 * </desc>
 *
 * @createDate 2019/02/21
 */
@Service
@RefreshScope
public class CloudEntranceServiceImpl implements ICloudEntranceService{

    private static final Logger LOG = LoggerFactory.getLogger(CloudEntranceServiceImpl.class);

    @Autowired
    private RedisService redisService;

    @Autowired
    private ICloudEntranceDao iCloudEntranceDao;

    @Autowired
    IOperatePackageDao iOperatePackageDao;

    @Autowired
    ICloudIntercomDeviceServiceDao iCloudIntercomDeviceServiceDao;

    @Autowired
    private IDeviceEntranceInfoDao iDeviceEntranceInfoDao;

    @Autowired
    MessageSender messageSender;

    @Value("${" + PlatformConstants.CLOUD_ENTRANCE_TOKEN_KEY + "}")
    String cloudEntranceTokenKey;

    @Autowired
    ICloudElevatorDao iCloudElevatorDao;

    @Autowired
    IAppDeviceDao iAppDeviceDao;
    /**
     * <desc>
     *      检测门禁是否存在
     * </desc>
     *
     * @param sn
     * @param deviceType 17代表云门禁 22代表云联动器 22代表云联动器
     * @return
     * @author Jiaqi.X
     * @createDate 2019/02/21
     */
    @Override
    public String checkSnExists(String sn,Integer doorCount,String deviceType) {
        List<String> deviceUniques = this.getDeviceListBySnAndDoorCount(sn,doorCount);
        if(deviceType.equals(PropertyEquipTypeEnum.CLOUD_ENTRANCE.getType().toString())){
            return iCloudEntranceDao.checkSnExists(deviceUniques);
        }else if(deviceType.equals(PropertyEquipTypeEnum.CLOUD_UNIBODY_FACE_DEVICE.getType().toString())){
            return iCloudEntranceDao.checkSnExistsByUnibodyFace(deviceUniques);
        }else if(deviceType.equals(PropertyEquipTypeEnum.HARDWARE_CLOUD_UNIBODY_ENTRANCE_DEVICE.getType().toString())){
            return iCloudEntranceDao.checkSnExistsByUnibodyEntrance(deviceUniques);
        } else{
            return iCloudEntranceDao.checkSnExistsByWippen(deviceUniques);
        }

    }

    /**
     * <desc>
     *      云门禁登录
     * </desc>
     *
     * @param sn
     * @param doorCount 控制器控制门数
     * @param encryptionAbility 加密传输方法 0不加密传输 1自有加密方案 2https安全传输
     * @return
     * @author Jiaqi.X
     * @createDate 2019/02/21
     */
    @Override
    public CloudEntranceVO login(String sn, Integer doorCount,Integer encryptionAbility, String deviceType) throws Exception {
        CloudEntranceVO vo = new CloudEntranceVO();
        //一体式门禁不支持华为iot 因此特殊处理
        if("24".equals(deviceType)) {
            vo = iCloudEntranceDao.login1(this.getDeviceListBySnAndDoorCount(sn,doorCount));
        }else {
            vo = iCloudEntranceDao.login(this.getDeviceListBySnAndDoorCount(sn,doorCount));
        }

        vo.setSn(sn);
        vo.setMainDeviceUnique(String.format("%s%s%s", StringHandlerUtil.getProjectIdBySn(sn),"2",
                StringHandlerUtil.autlSupply(4,sn.substring(sn.length()-4,sn.length()),"0")));
        vo.setDoorCount(doorCount);
        vo.setSubDeviceUnique(StringUtils.join(this.getDeviceListBySnAndDoorCount(sn, doorCount), ","));
        //设置token
        vo.setToken(UserTokenUtil.tokenEncrypt(String.format("%s%s%s",sn,"|", DateUtil.fomatDate(new Date(),DateUtil.DATE_FORMAT_TYPE2)),
                cloudEntranceTokenKey, SystemTypeEnum.CLOUD_ELEVATOR_SERVER.getType()));
        vo.setEncryptMethod(encryptionAbility != null ? encryptionAbility : 0);
        List<CloudIntercomDeviceVO.PropertyValue> list = iCloudIntercomDeviceServiceDao.getPropertyInfo(vo.getProjectId(),3);
        if (list.size() == 0) {
            list = new ArrayList<>();
            list.add(new CloudIntercomDeviceVO.PropertyValue());
        }
        vo.setDeploys(list);
        List<CloudIntercomDeviceVO.PropertyValue> listElevator = iCloudIntercomDeviceServiceDao.getPropertyInfo(vo.getProjectId(),2);
        if (listElevator.size() == 0) {
            listElevator = new ArrayList<>();
            listElevator.add(new CloudIntercomDeviceVO.PropertyValue());
        }
        vo.setElevatorDeploys(listElevator);
        //如果iot账号为空或不等于当前设备的sn，以当前sn的设备序列号创建新阿里云账号，或使用已有的阿里云账号
        if(StringUtils.isBlank(vo.getIotDeviceId()) ||
                (StringUtils.isNotBlank(vo.getIotDeviceName()) && !vo.getIotDeviceName().equals(StringHandlerUtil.getEntranceDeviceUniqueBySn(sn)))
                ||(StringUtils.isNotBlank(vo.getHuaweiIotId()) && !sn.equals(vo.getHuaweiIotId().substring(vo.getHuaweiIotId().indexOf("_")+1,vo.getHuaweiIotId().length())))
                ){
            //向阿里云iot中心注册设备 注册成功后更新设备信息
            Map<String, Object> params = new HashMap<>();
            params.put("deviceOperateIotType", DeviceIotEnum.REGIST_DEVICE.getCommandType());
            params.put("productKey", vo.getIotProductKey());
            params.put("deviceUnique",vo.getSubDeviceUnique());
            if(StringUtils.isNotBlank(deviceType)) {
                params.put("deviceType",deviceType);
            }
            Map<String,Object> result=new HashMap<>();
            result.put("data",params);
            messageSender.send(RabbitMQConstant.RABBITMQ_DEVICE_ELEVATOR_QUEUE, JsonUtil.toJSON(result),
                    RabbitMQConstant.RABBITMQ_DEVICE_ELEVATOR_EXCHANGE,RabbitMQConstant.RABBITMQ_DEVICE_ELEVATOR_KEY);
        }
        vo.setInvalidTime(DateUtil.fomatDate(
                DateUtils.addSeconds(new Date(), RedisConstant.CLOUD_ENTRANCE_LOGIN_TIME.intValue()),
                "yyyy-MM-dd HH:mm:ss"
        ));
        //设置缓存
        redisService.set(RedisConstant.CLOUD_ENTRANCE_LOGIN_REDIS_KEY + vo.getSn(),
                RedisConstant.CLOUD_ENTRANCE_LOGIN_TIME, vo);
        //清除过期轮询命令
        iCloudEntranceDao.cleanOrders(StringHandlerUtil.splitString(vo.getSubDeviceUnique()));
        return vo;
    }

    /**
     * <desc>
     *      从缓存中获取当前登录门禁信息
     * </desc>
     *
     * @param token
     * @return
     * @author Jiaqi.X
     * @createDate 2019/02/21
     */
    @Override
    public CloudEntranceVO retrieve(String token) {
        try {
            if (StringUtils.isBlank(token)) {
                return null;
            }
            //解密token获取设备sn
            String decrypt = UserTokenUtil.tokenDecrypt(token, cloudEntranceTokenKey);
            String sn = UserTokenUtil.tokenDecrypt(token, cloudEntranceTokenKey).substring(0,decrypt.indexOf("%"));
            if (StringUtils.isBlank(sn)) {
                return null;
            }
            CloudEntranceVO entrance = (CloudEntranceVO) redisService.getObject(RedisConstant.CLOUD_ENTRANCE_LOGIN_REDIS_KEY + sn, CloudEntranceVO.class);
            //判断是否是异地登录
            if(entrance!=null && !entrance.getToken().equals(token)){
                entrance.setStatus(2);
            }
            return entrance;
        }catch (Exception e){
            return null;
        }
    }

    /**
     * <desc>
     *      通过sn及门的数量获取控制器管控的门禁设备序列号集合
     * </desc>
     *
     * @param sn
     * @param doorCount
     * @return
     * @author Jiaqi.X
     * @createDate 2019/02/22
     */
    private List<String> getDeviceListBySnAndDoorCount(String sn,Integer doorCount){
        List<String> devices = new ArrayList<>();
        Integer deviceId= Integer.valueOf(sn.substring(sn.length() - 4, sn.length()));
        for(int i = deviceId ; i < deviceId+doorCount ; i++ ){
            devices.add(String.format("%s%s%s", StringHandlerUtil.getProjectIdBySn(sn),"2",StringHandlerUtil.autlSupply(4,i+"","0")));
        }
        return devices;
    }

    /**
     * <desc>
     *      更新云门禁缓存iot信息
     * </desc>
     *
     * @param cloudEntranceVO
     * @return
     * @author Juguang.S
     * @createDate 2019/02/26
     */
    @Override
    public CloudEntranceVO updateCloudEntranceIotCacheInfo(CloudEntranceVO cloudEntranceVO) {
        List<String> deviceUniques = getDeviceListBySnAndDoorCount(cloudEntranceVO.getSn(),cloudEntranceVO.getDoorCount());
        CloudEntranceVO dbVo = iCloudEntranceDao.getDeviceInfoBySn(deviceUniques);
        cloudEntranceVO.setIotDeviceId(dbVo.getIotDeviceId());
        cloudEntranceVO.setIotDeviceSecret(dbVo.getIotDeviceSecret());
        cloudEntranceVO.setIotDeviceStatus(dbVo.getIotDeviceStatus());
        cloudEntranceVO.setIotDeviceWorkStatus(dbVo.getIotDeviceWorkStatus());
        cloudEntranceVO.setIotVersion(dbVo.getIotVersion());
        List<CloudIntercomDeviceVO.PropertyValue> list = iCloudIntercomDeviceServiceDao.getPropertyInfo(dbVo.getProjectId(),3);
        if (list.size() == 0) {
            list = new ArrayList<>();
            list.add(new CloudIntercomDeviceVO.PropertyValue());
        }
        cloudEntranceVO.setDeploys(list);
        cloudEntranceVO.setChargeMode(dbVo.getChargeMode());
        cloudEntranceVO.setEquipMode(dbVo.getEquipMode());
        if(StringUtils.isNotBlank(cloudEntranceVO.getIotDeviceId())){
            //如果iot信息不为空，则更新缓存
            cloudEntranceVO.setInvalidTime(DateUtil.fomatDate(
                    DateUtils.addSeconds(new Date(), RedisConstant.CLOUD_ENTRANCE_LOGIN_TIME.intValue()),
                    "yyyy-MM-dd HH:mm:ss"
            ));
            redisService.set(RedisConstant.CLOUD_ENTRANCE_LOGIN_REDIS_KEY + cloudEntranceVO.getSn(),
                    RedisConstant.CLOUD_ENTRANCE_LOGIN_TIME, cloudEntranceVO);
        }
        return cloudEntranceVO;
    }

    /**
     * <desc>
     *      根据sn查询该设备信息
     * </desc>
     *
     * @param sn
     * @return
     * @author Juguang.S
     * @createDate 2019/02/26
     */
    @Override
    public Map<String, Object> getDeviceInfoBySn(String sn,Integer doorCount) {
        List<String> deviceUniques = getDeviceListBySnAndDoorCount(sn,doorCount);
        CloudEntranceVO vo = iCloudEntranceDao.getDeviceInfoBySn(deviceUniques);
        Map<String, Object> map = new HashMap<>();
        map.put("projectName", vo.getProjectName());
        map.put("deviceName", vo.getDeviceName());
        map.put("rootPwd", vo.getRootPwd());
        map.put("rootPort", vo.getRootPort());
        map.put("iotProductKey", vo.getIotProductKey());
        map.put("iotDeviceId",vo.getIotDeviceId());
        map.put("iotPlatform",vo.getIotPlatform());
        map.put("iotDevicePassword",vo.getIotDevicePassword());
        map.put("doorStatus",iCloudEntranceDao.getBatchDeviceStatus(deviceUniques));
        return map;
    }

    /** <desc>
     *      门禁状态上报控制
     * </desc>
     *
     * @param sourceForm 来源 默认itlong
     * @param mainDeviceUnique 控制器门禁设备序列号
     * @param doorNum   需要控制的门禁设备序列号，多个,号分隔
     * @param timeout 超时时长 范围0-300，0表示设备立刻停止上报
     * @param productKey iot产品key
     *
     * @author Jiaqi.X
     * @createDate 2019/02/27
     */
    public void entranceStatusCtrl(String sourceForm,String mainDeviceUnique,String doorNum,String timeout,String productKey) throws Exception {
        ProjectIotInfo projectIotInfo = iAppDeviceDao.getProjectIotInfoByProjectId(StringHandlerUtil.getProjectIdByDeviceUnique(mainDeviceUnique), mainDeviceUnique,
                StringHandlerUtil.getDeviceTypeByDeviceUnique(mainDeviceUnique));
        String[] entrances = StringHandlerUtil.splitString(doorNum);
        if(projectIotInfo.getIotFlag()==1) {
            List<Map<String, Object>> messages = new ArrayList<>();
            //通过productKey获取门禁的版本
            Integer version = iCloudEntranceDao.getIotVersionByProductKey(productKey);
            for (String entrance : entrances) {
                Map<String, Object> message = new HashMap<>();
                message.put("productKey", productKey);
                message.put("topic", "/" + (version == 1 ? mainDeviceUnique + "/user" : mainDeviceUnique) + IotCloudCtrlInstructEnum.DEVICECMD.getUrl());
                IotPubMessageDTO dto = new IotPubMessageDTO();
                dto.setSourceForm(sourceForm);
                dto.setCmd("1001");
                dto.setSnr(1);
                Map<String, Object> data = new HashMap<>();
                data.put("doorNum", entrance);
                data.put("timeout", timeout);
                dto.setData(data);
                message.put("message", JsonUtil.toJSON(dto));
                messages.add(message);
            }
            this.sendCloudEntranceMessage(messages);
        }else{
            for (String entrance : entrances) {
                Map<String, Object> data = new HashMap<>();
                Map<String, Object> message = new HashMap<>();
                Map<String,Object> customData = new HashMap<>();
                data.put("serviceId", "SettingService");
                data.put("commandName", "deviceReportCtrl");
                data.put("deviceId",projectIotInfo.getHuaweiIotId());
                message.put("sourceFrom", sourceForm);
                message.put("snr", LogicIdUtil.userBusinessId());
                message.put("cmd", "1001");
                message.put("timestamp", (System.currentTimeMillis() + 20000) + "");
                message.put("doorNum", entrance);
                message.put("timeout",timeout);
                message.put("customData",JsonUtil.toJSON(customData));
                data.put("message",message);
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("data",data);
                LOG.info("时区信息:{}", DateUtil.getDetailDateTime());
                messageSender.send(RabbitMQConstant.RABBITMQ_HUAW_CALL_IOT_PUB_QUEUE, jsonObject.toJSONString(),
                        RabbitMQConstant.RABBITMQ_IOT_PUB_EXCHANGE, RabbitMQConstant.RABBITMQ_HUAW_CALL_IOT_PUB_KEY);
            }
        }
    }

    /**
     * <desc>
     *      门禁开放控制指令
     * </desc>
     *
     * @param sourceForm 来源 默认itlong
     * @param mainDeviceUnique 控制器门禁设备序列号
     * @param doorNum   子门禁设备机号，多个，号分隔
     * @param openCtrl  开门控制类型：0关门 1开门
     * @param timeout 开门时长：范围 0-300，0保持常开，1-300开门时长，单位s
     * @param productKey iot产品key
     * @param userId 开门用户id
     * @param correlationId 开门事件唯一id
     * @param robotFlag 机器人标识,1为机器人开门
     *
     * @author Jiaqi.X
     * @createDate 2019/02/27
     */
    public void entranceOpenOrCloseCtrl(String sourceForm,String mainDeviceUnique,String doorNum,
                                        String openCtrl,String timeout,String productKey,String userId,String correlationId,String robotFlag) throws Exception {
        ProjectIotInfo projectIotInfo = iAppDeviceDao.getProjectIotInfoByProjectId(StringHandlerUtil.getProjectIdByDeviceUnique(mainDeviceUnique),mainDeviceUnique,
                StringHandlerUtil.getDeviceTypeByDeviceUnique(mainDeviceUnique));
        String[] entrances = StringHandlerUtil.splitString(doorNum);
        if(projectIotInfo.getIotFlag() == 1) {
            List<Map<String, Object>> messages = new ArrayList<>();
            //通过productKey获取门禁的版本
            Integer version = iCloudEntranceDao.getIotVersionByProductKey(productKey);
            for (String entrance : entrances) {
                Map<String, Object> message = new HashMap<>();
                message.put("productKey", productKey);
                message.put("topic", "/" + (version == 1 ? mainDeviceUnique + "/user" : mainDeviceUnique) + IotCloudCtrlInstructEnum.DEVICECMD.getUrl());
                IotPubMessageDTO dto = new IotPubMessageDTO();
                dto.setSourceForm(sourceForm);
                dto.setCmd("1003");
                dto.setSnr(1);
                Map<String, Object> data = new HashMap<>();
                data.put("cmdVer", "0");
                data.put("doorNum", entrance);
                data.put("openCtrl", openCtrl);
                data.put("userId", userId);
                data.put("timeout", timeout);
                data.put("correlationId", correlationId);
                data.put("robotFlag", robotFlag);
                dto.setData(data);
                message.put("message", JsonUtil.toJSON(dto));
                messages.add(message);
            }
            this.sendCloudEntranceMessage(messages);
        }else{
            for (String entrance : entrances) {
                Map<String, Object> data = new HashMap<>();
                Map<String, Object> message = new HashMap<>();
                Map<String,Object> customData = new HashMap<>();
                data.put("serviceId", "SettingService");
                data.put("commandName", "doorCtrl");
                data.put("deviceId",projectIotInfo.getHuaweiIotId());
                message.put("sourceFrom", sourceForm);
                message.put("snr", LogicIdUtil.userBusinessId());
                message.put("cmd", "1003");
                message.put("timestamp", (new Date()).getTime()+"");
                message.put("cmdVer", "0");
                message.put("doorNum", entrance);
                message.put("openCtrl",openCtrl);
                message.put("timeout",timeout);
                message.put("userId", userId);
                //时区
                LOG.info("时区信息:{}", DateUtil.getDetailDateTime());
                // 是VIP为 true
                boolean appUserIsVipFlag = appUserIsVip(userId, StringHandlerUtil.getProjectIdByDeviceUnique(mainDeviceUnique));
                // 用户标签，1-VIP
                Integer appUserVip = 1;
                if(appUserIsVipFlag) {
                    message.put("isVip", appUserVip);
                }
                message.put("correlationId",correlationId);
                if(StringUtils.isNotBlank(robotFlag)){
                    customData.put("robotFlag",robotFlag);
                }
                message.put("customData",JsonUtil.toJSON(customData));
                data.put("message",message);
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("data",data);
                messageSender.send(RabbitMQConstant.RABBITMQ_HUAW_CALL_IOT_PUB_QUEUE, jsonObject.toJSONString(),
                        RabbitMQConstant.RABBITMQ_IOT_PUB_EXCHANGE, RabbitMQConstant.RABBITMQ_HUAW_CALL_IOT_PUB_KEY);
            }
        }
    }

    /**
     * <desc>
     *      联动器开放控制指令
     * </desc>
     *
     * @param sourceForm 来源 默认itlong
     * @param mainDeviceUnique 控制器门禁设备序列号
     * @param doorNum   子门禁设备机号，多个，号分隔
     * @param openCtrl  开门控制类型：0关门 1开门
     * @param timeout 开门时长：范围 0-300，0保持常开，1-300开门时长，单位s
     * @param productKey iot产品key
     * @param userId 开门用户id
     * @param type 开门类型
     * @param doorDirection 门方向:0背门,1正门
     * @param floor 真实楼层例:1,2,3,4
     * @param correlationId 开门事件唯一id
     * @param robotFlag 机器人标识,1为机器人开门
     *
     * @author Qiang.S
     * @createDate 2019/05/27
     */
    public void wippenOpenOrCloseCtrl(String sourceForm,String mainDeviceUnique,String doorNum,
                                      String openCtrl,String timeout,String productKey,String userId,String type,
                                      String doorDirection,String floor,String correlationId,String robotFlag,String modeFloor) throws Exception {
        ProjectIotInfo projectIotInfo = iAppDeviceDao.getProjectIotInfoByProjectId(StringHandlerUtil.getProjectIdByDeviceUnique(mainDeviceUnique),mainDeviceUnique,
                StringHandlerUtil.getDeviceTypeByDeviceUnique(mainDeviceUnique));
        String[] entrances = StringHandlerUtil.splitString(doorNum);
        if(projectIotInfo.getIotFlag() == 1) {
            List<Map<String, Object>> messages = new ArrayList<>();
            //通过productKey获取门禁的版本
            Integer version = iCloudEntranceDao.getIotVersionByProductKey(productKey);
            for (String entrance : entrances) {
                Map<String, Object> message = new HashMap<>();
                message.put("productKey", productKey);
                message.put("topic", "/" + (version == 1 ? mainDeviceUnique + "/user" : mainDeviceUnique) + IotCloudCtrlInstructEnum.DEVICECMD.getUrl());
                IotPubMessageDTO dto = new IotPubMessageDTO();
                dto.setSourceForm(sourceForm);
                dto.setCmd("1003");
                dto.setSnr(1);
                Map<String, Object> data = new HashMap<>();
                data.put("cmdVer", "0");
                data.put("doorNum", entrance);
                data.put("openCtrl", openCtrl);
                data.put("userId", openCtrl.equals("1") ? userId : "");
                data.put("timeout", timeout);
                data.put("correlationId", correlationId);
                data.put("robotFlag", robotFlag);
                data.put("type", type);
                if (StringUtils.isBlank(doorDirection)) {
                    data.put("frontFloor", "");
                    data.put("backFloor", "");
                } else if (doorDirection.contains("0") && doorDirection.contains("1")) {
                    data.put("frontFloor", floor == null || floor.split(":").length < 2 ? "" : floor.split(":")[1]);
                    data.put("backFloor", floor == null || floor.split(":").length < 2 ? "" : floor.split(":")[0]);
                } else if (doorDirection.contains("1") && !doorDirection.contains("0")) {
                    data.put("frontFloor", floor == null || floor.split(":").length < 1 ? "" : floor.split(":")[0]);
                    data.put("backFloor", "");
                } else if (doorDirection.contains("0") && !doorDirection.contains("1")) {
                    data.put("frontFloor", "");
                    data.put("backFloor", floor == null || floor.split(":").length < 1 ? "" : floor.split(":")[0]);
                }
                data.put("modeFloor","1".equals(modeFloor)?modeFloor:null);
                dto.setData(data);
                message.put("message", JsonUtil.toJSON(dto));
                messages.add(message);
            }
            this.sendCloudEntranceMessage(messages);
        }else{
            for (String entrance : entrances) {
                Map<String, Object> data = new HashMap<>();
                Map<String, Object> message = new HashMap<>();
                Map<String,Object> customData = new HashMap<>();
                data.put("serviceId", "SettingService");
                data.put("commandName", "doorCtrl");
                data.put("deviceId",projectIotInfo.getHuaweiIotId());
                message.put("sourceFrom", sourceForm);
                message.put("snr", LogicIdUtil.userBusinessId());
                message.put("cmd", "1003");
                message.put("timestamp", (new Date()).getTime()+"");
                message.put("cmdVer", "0");
                message.put("doorNum", entrance);
                message.put("openCtrl",openCtrl);
                message.put("timeout",timeout);
                message.put("userId", openCtrl.equals("1") ? userId : "");
                LOG.info("时区信息:{}", DateUtil.getDetailDateTime());
                // 是VIP为 true
                boolean appUserIsVipFlag = appUserIsVip(userId, StringHandlerUtil.getProjectIdByDeviceUnique(mainDeviceUnique));
                // 用户标签，1-VIP
                Integer appUserVip = 1;
                if(appUserIsVipFlag) {
                    message.put("isVip", appUserVip);
                }
                message.put("correlationId",correlationId);
                message.put("type", type);
                if(StringUtils.isNotBlank(robotFlag)){
                    customData.put("robotFlag",robotFlag);
                }
                if (StringUtils.isBlank(doorDirection)) {
                    message.put("frontFloor", "");
                    message.put("backFloor", "");
                } else if (doorDirection.contains("0") && doorDirection.contains("1")) {
                    message.put("frontFloor", floor == null || floor.split(":").length < 2 ? "" : floor.split(":")[1]);
                    message.put("backFloor", floor == null || floor.split(":").length < 2 ? "" : floor.split(":")[0]);
                } else if (doorDirection.contains("1") && !doorDirection.contains("0")) {
                    message.put("frontFloor", floor == null || floor.split(":").length < 1 ? "" : floor.split(":")[0]);
                    message.put("backFloor", "");
                } else if (doorDirection.contains("0") && !doorDirection.contains("1")) {
                    message.put("frontFloor", "");
                    message.put("backFloor", floor == null || floor.split(":").length < 1 ? "" : floor.split(":")[0]);
                }
                message.put("customData",JsonUtil.toJSON(customData));
                message.put("modeFloor","1".equals(modeFloor)?modeFloor:null);
                data.put("message",message);
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("data",data);
                messageSender.send(RabbitMQConstant.RABBITMQ_HUAW_CALL_IOT_PUB_QUEUE, jsonObject.toJSONString(),
                        RabbitMQConstant.RABBITMQ_IOT_PUB_EXCHANGE, RabbitMQConstant.RABBITMQ_HUAW_CALL_IOT_PUB_KEY);
            }
        }
    }

    /**
     * <desc>
     *      用户是否是vip
     * <desc/>
     *
     * @param userId 用户编号
     * @param projectId 项目编号
     * @return
     * @author caoshuai
     * @createDate 2020-12-11
     */

    private boolean appUserIsVip(String userId, String projectId) throws Exception {
        //用户标签，1-VIP，2-障碍人士，多个英文逗号连接
        String  userLabel  = iAppDeviceDao.getAppUserLabel(userId,projectId);
        if(StringUtils.isNotEmpty(userLabel)){
            String[]  labelList =  userLabel.split(",");
            for(String  label:labelList){
                //1是vip
                if("1".equals(label)){
                    return  true;
                }
            }
        }
        return false;
    }
    public static void main(String[] args) {
        Map<String, Object> map = new HashMap<>();
        String modeFloor = null;
        map.put("1","1".equals(modeFloor)?modeFloor:null);
    }

    /**
     * <desc>
     *      设置门禁工作模式
     * </desc>
     *
     * @sourceForm 来源 默认itlong
     * @param mainDeviceUnique  控制器设备序列号
     * @param doorNum   子门禁机号，多个，号分隔
     * @param mode  门禁工作模式，备用
     * @param productKey iot产品key
     *
     * @author Jiaqi.X
     * @createDate 2019/02/27
     */
    public void setEntranceOfficeStatus(String sourceForm,String mainDeviceUnique,String doorNum,String mode,String productKey) throws Exception {
        List<Map<String,Object>>  messages = new ArrayList<>();
        String[] entrances = StringHandlerUtil.splitString(doorNum);
        //通过productKey获取门禁的版本
        Integer version = iCloudEntranceDao.getIotVersionByProductKey(productKey);
        for(String entrance : entrances){
            Map<String,Object> message = new HashMap<>();
            message.put("productKey",productKey);
            message.put("topic","/" + (version == 1 ? mainDeviceUnique+"/user" : mainDeviceUnique)+ IotCloudCtrlInstructEnum.DEVICECMD.getUrl());
            IotPubMessageDTO dto = new IotPubMessageDTO();
            dto.setSourceForm(sourceForm);
            dto.setCmd("1005");
            dto.setSnr(1);
            Map<String,Object> data = new HashMap<>();
            data.put("doorNum",entrance);
            data.put("mode",mode);
            dto.setData(data);
            message.put("message",JsonUtil.toJSON(dto));
            messages.add(message);
        }
        this.sendCloudEntranceMessage(messages);
    }


    /**
     * <desc>
     *      发布消息到iot中心
     * </desc>
     *
     * @param messages
     * @author Jiaqi.X
     * @createDate 2019/02/27
     */
    private void sendCloudEntranceMessage(List<Map<String,Object>> messages) throws Exception {
        if(!messages.isEmpty()){
            Map<String,Object> params = new HashMap<>();
            params.put("deviceOperateIotType", DeviceIotEnum.PUB_MESSAGE.getCommandType());
            params.put("devices",messages);
            JSONObject obj = new JSONObject();
            obj.put("data",params);
            messageSender.send(RabbitMQConstant.RABBITMQ_IOT_PUB_QUEUE, obj.toJSONString(),
                    RabbitMQConstant.RABBITMQ_IOT_PUB_EXCHANGE, RabbitMQConstant.RABBITMQ_IOT_PUB_KEY);
        }
    }


    /**
     * <desc>
     *      添加云门禁用户身份证通行记录
     * </desc>
     *
     * @param userInfo 用户信息
     * @author wangzhi
     * @createDate 2019/02/28
     */
    @Override
    public Integer saveIdCardPassRecord(Map<String, Object> userInfo) throws Exception {
        TimeTaskDevicePassRecordPO po=new TimeTaskDevicePassRecordPO();
        po.setPdId(LogicIdUtil.bussinessId());
        po.setUserId(StringHandlerUtil.getNullOrStringForObject(userInfo.get("userId")));
        po.setProjectId(StringHandlerUtil.getNullOrStringForObject(userInfo.get("projectId")));
        po.setDeviceType(PropertyEquipTypeEnum.CLOUD_ENTRANCE.getType());
        po.setDeviceUnique(StringHandlerUtil.getEntranceDeviceUniqueBySn(StringHandlerUtil.getNullOrStringForObject(userInfo.get("sn"))));
        DeviceEntranceInfoPO deviceEntranceInfoPO = iCloudEntranceDao.getDeviceInfoByDeviceUnique(po.getDeviceUnique());
        po.setDeviceName(deviceEntranceInfoPO.getDeviceName());
        po.setOpenType(OpenTypeEnum.BY_IDCARD_KEY.getType());
        po.setPassTime(new Date());
        po.setUploadTime(new Date());
        po.setIsOpen(0);
        po.setSynchro(0);
        po.setSource(4);
        po.setStatus(DataStatusEnum.NORMAL.getType());
        po.setCreateTime(new Date());
        return iCloudEntranceDao.save(SqlUtil.durableData(po,PlatformConstants.TABLE_SAVE));
    }

    /**
     * <desc>
     *      获取云门禁轮询命令
     * <desc/>
     *
     * @param getDTO 轮询命令分页
     * @return
     * @author Qiang.S
     * @createDate 2019-03-04
     */
    @Override
    public Page<CloudEntranceChangeLogPageVO> getDeviceChangeLogOrders(CloudIntercomChangeLogGetDTO getDTO) throws Exception {
        //将DTO转换为Map params
        Map<String, Object> selectParams = SqlUtil.convertBeanToMapParams(getDTO);
        //1.分页获取待处理命令
        Page<CloudEntranceChangeLogPageVO> page = new Page<>();
        page.getPage().setCurrentPage("1");
        page.getPage().setPageSize(getDTO.getPageSize().toString());
        selectParams.put("currentPage",page.getPage().getStartSlip());
        selectParams.put("pageSize",page.getPage().getPageSize());
        List<CloudEntranceChangeLogPageVO> orderVOS =
                iCloudEntranceDao.getChangeLogPage(selectParams);
        Integer count = iCloudEntranceDao.getChangeLogPageCount(getDTO.getSn());
        //填充返回数据集
        page.setRows(orderVOS, count);

        //2.对命令做后续处理
        if (null != orderVOS && !orderVOS.isEmpty()){
            //a.将commandData转换为JSONObject
            for (CloudEntranceChangeLogPageVO orderVO: orderVOS){
                //全量更新时，commandData不是json格式
                if (orderVO.getCommandData() != null &&
                        !PushCloudEntranceChangeEnum.PUSH_FULL.getType().toString().equals(orderVO.getCommandType())){
                    orderVO.setCommandData(JSON.parse(orderVO.getCommandData().toString()));
                }
            }
            //b.将命令标记为处理中
            String[] idArr = new String[orderVOS.size()];
            for (int i = 0; i< idArr.length; i++){
                idArr[i] = orderVOS.get(i).getId();
            }
            iCloudEntranceDao.changeChangeLogOrdersStatus(getDTO.getSn(), idArr, 1);
        }
        //此处需校验一个控制器所管控的门数有没变化，需有变化则更新绑定关系
        //根据sn查询以该sn作为控制器的设备
        List<String> oldSnList = iDeviceEntranceInfoDao.getSnbyBingDeviceGroup(getDTO.getSn());
        List<String> snList = StringHandlerUtil.getSnByDoorNum(getDTO.getSn(),getDTO.getDoorCount());
        if(oldSnList != null && !oldSnList.isEmpty() && oldSnList.size()!=snList.size()){
            Map<String,Object> params = new HashMap<>();
            params.put("snList",snList);
            params.put("sn",getDTO.getSn());
            iDeviceEntranceInfoDao.updateEntranceInfoForDoorCount(params);
        }
        return page;
    }

    /**
     * <desc>
     *     云门禁设备批量完成轮询命名
     * </desc>
     *
     * @param sn
     * @param ids 轮询命令，多个以英文逗号拼接
     * @return 受影响的行数
     * @throws Exception
     * @author Qiang.S
     * @createDate 2019-03-04
     */
    @Override
    public Integer batchFinishChangeLogOrders(String sn, String ids) throws Exception {
        String[] idArr = StringHandlerUtil.splitString(ids);
        return iCloudEntranceDao.changeChangeLogOrdersStatus(sn, idArr, 2);
    }

    /**
     * <desc>
     *     通知云端升级失败原因
     * </desc>
     *
     * @param sn
     * @param id 轮询命令
     * @param msg 失败原因
     * @return 受影响的行数
     * @throws Exception
     * @author Qiang.S
     * @createDate 2019-06-25
     */
    @Override
    public Integer reportUpdateResult(String sn, String id, String msg) throws Exception {
        return iCloudEntranceDao.reportUpdateResult(sn, id, 3, msg);
    }

    /**
     *      获取iot门禁账号及关联的产品id
     * </desc>
     *
     * @param deviceUnique
     * @return
     * @author Jiaqi.X
     * @createDate 2019/03/04
     */
    @Override
    public Map<String, Object> getMainDeviceUniqueAndProductKey(String deviceUnique) {
        return iCloudEntranceDao.getMainDeviceUniqueAndProductKey(deviceUnique);
    }

    /**
     *      获取iot门禁账号及关联的产品id
     * </desc>
     *
     * @param projectId
     * @return
     * @author Jiaqi.X
     * @createDate 2019/03/04
     */
    @Override
    public List<Map<String, Object>> getMainDeviceUniqueAndProductKeyByProjectId(String projectId) {
        return iCloudEntranceDao.getMainDeviceUniqueAndProductKeyByProjectId(projectId);
    }

    /**
     * <desc>
     *      获取云门禁或联动器设备更新信息
     * </desc>
     *
     * @param sn
     * @param productType 2云门禁,4联动器
     * @return
     * @author Qiang.S
     * @createDate 2018/08/30
     */
    @Override
    public CloudDeviceUpdateInfoVO deviceEntranceUpdate(String sn, String productType) throws Exception {
        //根据sn,查询指令
        List<CloudIntercomChangeLogOrderVO> list = iCloudEntranceDao.getUpdateDeviceInfo(sn);
        if (list.size() == 0) {//无此设备升级命令
            return null;
        }
        StringBuffer ids = new StringBuffer();
        //取消所有沉余指令
        for (int i=1;i<list.size();i++) {
            ids.append(list.get(i).getId().toString()+",");
        }
        String[] id = ids.toString().split(",");

        OperateUpdateDetailVO operateUpdateDetailVO = iOperatePackageDao.getUpdateDetailForDeviceUpdate(list.get(0).getCommandData().toString(),"",DeviceTypeEnum.DEVICE_CLOUD_LINUX_SCM.getType().toString(),productType);
        if (operateUpdateDetailVO == null) {
            return null;
        }
        CloudDeviceUpdateInfoVO cloudDeviceUpdateInfoVO = new CloudDeviceUpdateInfoVO();
        cloudDeviceUpdateInfoVO.setCommandId(list.get(0).getId().toString());
        cloudDeviceUpdateInfoVO.setFileName(operateUpdateDetailVO.getUpdateName());
        cloudDeviceUpdateInfoVO.setMd5(operateUpdateDetailVO.getMd5());
        cloudDeviceUpdateInfoVO.setVersionCode(operateUpdateDetailVO.getVersion());
        cloudDeviceUpdateInfoVO.setUrl(operateUpdateDetailVO.getUpdateUrl());

        //将所有沉余指令清除
        iCloudEntranceDao.changeChangeLogOrdersStatus(sn,id,2);
        //将执行的指令调整为 处理中
        String[] newId = {list.get(0).getId().toString()};
        iCloudEntranceDao.changeChangeLogOrdersStatus(sn,newId,1);
        return cloudDeviceUpdateInfoVO;
    }

    /**
     * <desc>
     *      获取一体式人脸识别门禁更新信息
     * </desc>
     *
     * @param sn
     * @param deviceType 软件类型 4 维护程序，5 业务程序，6 桌面程序，7 通信程序
     * @return
     * @author Qiang.S
     * @createDate 2020/05/25
     */
    @Override
    public CloudDeviceUpdateInfoVO deviceUnibodyFaceUpdate(String sn, String deviceType) throws Exception {
        //根据sn,查询指令
        List<CloudIntercomChangeLogOrderVO> list = iCloudEntranceDao.getUpdateDeviceInfo(sn);
        if (list.size() == 0) {//无此设备升级命令
            return null;
        }
        StringBuffer ids = new StringBuffer();
        //取消所有沉余指令
        for (int i=1;i<list.size();i++) {
            ids.append(list.get(i).getId().toString()+",");
        }
        String[] id = ids.toString().split(",");

        OperateUpdateDetailVO operateUpdateDetailVO = iOperatePackageDao.getUpdateDetailForDeviceUpdate(list.get(0).getCommandData().toString(),"",deviceType,"6");
        if (operateUpdateDetailVO == null) {
            return null;
        }
        CloudDeviceUpdateInfoVO cloudDeviceUpdateInfoVO = new CloudDeviceUpdateInfoVO();
        cloudDeviceUpdateInfoVO.setCommandId(list.get(0).getId().toString());
        cloudDeviceUpdateInfoVO.setFileName(operateUpdateDetailVO.getUpdateName());
        cloudDeviceUpdateInfoVO.setMd5(operateUpdateDetailVO.getMd5());
        cloudDeviceUpdateInfoVO.setVersionCode(operateUpdateDetailVO.getVersion());
        cloudDeviceUpdateInfoVO.setUrl(operateUpdateDetailVO.getUpdateUrl());

        //将所有沉余指令清除
        iCloudEntranceDao.changeChangeLogOrdersStatus(sn,id,2);
        //将执行的指令调整为 处理中
        String[] newId = {list.get(0).getId().toString()};
        iCloudEntranceDao.changeChangeLogOrdersStatus(sn,newId,1);
        return cloudDeviceUpdateInfoVO;
    }

    /**
     * <desc>
     *      判断sn存在性
     * <desc/>
     *
     * @param sn
     * @return
     * @author Juguang.S
     * @createDate 2019-03-07
     */
    @Override
    public Integer checkSnExist(String sn) throws Exception {
        return iCloudEntranceDao.checkSnExist(sn);
    }

    /**
     * <desc>
     *      根据sn查询同为一个控制器的设备唯一码
     * <desc/>
     *
     * @param sn
     * @return
     * @author Qiang.S
     * @createDate 2019-03-14
     */
    @Override
    public List<String> getSameControllerDevice(String sn) throws Exception {
        return iDeviceEntranceInfoDao.getSameControllerDevice(sn);
    }

    /**
     * <desc>
     *      获取门禁设备iot信息
     * <desc/>
     *
     * @param deviceUnique 设备编号
     * @return
     * @author Qiang.S
     * @createDate 2019-03-15
     */
    @Override
    public CloudEntranceVO getDoorIotInfo(String deviceUnique) throws Exception {
        return iDeviceEntranceInfoDao.getDoorIotInfo(deviceUnique);
    }

    /**
     * <desc>
     *      根据房间ID查询对应的楼栋与单元ID
     * </desc>
     *
     * @param roomId 房间ID
     * @return 楼栋与单元ID
     * @author wangzhi
     * @createDate 2019/02/27
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public String deviceChangeLogGetBuildAndUnitIdByRoomId(String roomId) throws Exception {
        return iDeviceEntranceInfoDao.deviceChangeLogGetBuildAndUnitIdByRoomId(roomId);
    }

    /**
     * <desc>
     *      获取门禁黑名单分页列表
     * </desc>
     *
     * @param vo
     * @return
     * @author Jiaqi.X
     * @createDate 2019/10/14
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public DeviceBlackListPageVO<EntranceBlackListVO> pullBlackList(CloudEntranceVO vo) {
        //获取门禁信息
        String[] entrances = StringHandlerUtil.splitString(vo.getMainDeviceUnique() + "," + vo.getSubDeviceUnique());
        List<CloudEntranceVO> entranceList = iDeviceEntranceInfoDao.getEntranceInfos(entrances);
        DeviceBlackListPageVO<EntranceBlackListVO> page = new DeviceBlackListPageVO<>();
        page.setPage(Integer.valueOf(vo.getPage()));
        List<EntranceBlackListVO> list = new ArrayList<>();
        int currentPage = StringUtils.isNotBlank(vo.getPage()) ? Integer.valueOf(vo.getPage()) : 1;
        int pageSize = StringUtils.isNotBlank(vo.getPageSize()) ? Integer.valueOf(vo.getPageSize()) : 20;
        int startPage = (currentPage - 1) * pageSize;
        int endPage = (currentPage - 1) * pageSize + pageSize;
        int count = 0;
        int haveNext = 0;
        int currentCount = 0;
        Set<String> userIds = new HashSet<>();
        for (CloudEntranceVO entrance : entranceList) {
            String[] buildIds = StringHandlerUtil.splitString(entrance.getBuildIds());
            String[] unitIds = StringHandlerUtil.splitString(entrance.getUnitIds());
            EntranceBlackListVO entranceVO = new EntranceBlackListVO();
            entranceVO.setDoorNum(StringHandlerUtil.autlSupply(4,entrance.getMainDeviceUnique(),"0"));
            List<BlackListVO> blackList = new ArrayList<>();
            if ((buildIds != null && buildIds.length > 0)|| (unitIds != null && unitIds.length > 0)) {
                List<UserBlackInfoVO> users = iDeviceEntranceInfoDao.getUserBlackInfos(buildIds.length > 0 ? buildIds : null, unitIds.length > 0 ? unitIds : null, entrance.getProjectId());
                //地址用户
                for (UserBlackInfoVO user : users) {
                    if (count >= startPage && count <= endPage) {
                        if(userIds.add(user.getUid()+user.getRoomNo())) {
                            BlackListVO blackListVO = new BlackListVO();
                            blackListVO.setType(1);
                            blackListVO.setUid(StringHandlerUtil.autlSupply(8, user.getUid(), "0"));
                            blackListVO.setBatch(Integer.valueOf(user.getBatch()));
                            blackListVO.setRoomNo(StringHandlerUtil.autlSupply(2,Integer.toHexString(Integer.valueOf(user.getRoomNo())),"0"));
                            if (user.getUsableCount() == null || user.getUsableCount() <= 0) {
                                blackListVO.setStatus(1);
                                blackList.add(blackListVO);
                                count++;
                                currentCount++;
                            }
                        }
                    } else {
                        haveNext = 1;
                    }
                }
            }
            //临时权限用户
            List<UserBlackInfoVO> tempUsers = iDeviceEntranceInfoDao.getTempBlackInfos(entrance.getProjectId(),
                   Integer.valueOf(entrance.getMainDeviceUnique()));
            for (UserBlackInfoVO user : tempUsers) {
                if (count >= startPage && count <= endPage) {
                    if(userIds.add(user.getUid()+user.getRoomNo())) {
                        if (user.getUsableCount() == null || user.getUsableCount() <= 0) {
                            BlackListVO blackListVO = new BlackListVO();
                            blackListVO.setUid(StringHandlerUtil.autlSupply(8, user.getUid(), "0"));
                            blackListVO.setType(1);
                            blackListVO.setBatch(Integer.valueOf(user.getBatch()));
                            blackListVO.setRoomNo(StringHandlerUtil.autlSupply(2, Integer.toHexString(Integer.valueOf(user.getRoomNo())), "0"));
                            blackListVO.setStatus(1);
                            blackList.add(blackListVO);
                            count++;
                            currentCount++;
                        }
                    }
                } else {
                    haveNext = 1;
                }
            }
            entranceVO.setBlackListArr(blackList);
            list.add(entranceVO);
        }
        page.setBlackListArr(list);
        page.setTotal(count);
        page.setPage(currentPage);
        page.setCurrentTotal(currentCount);
        page.setHaveNext(haveNext);
        return page;
    }


    /**
     * <desc>
     *      获取门禁联动器临时权限
     * </desc>
     *
     * @param vo
     * @return
     * @author Jiaqi.X
     * @createDate 2019/10/14
     */
    @Override
    public DeviceAuthTempPageVO<EntranceTempAuthPageVO> getTempAuths(CloudEntranceVO vo) throws Exception {
        String date = DateUtil.fomatDate(new Date(),DateUtil.DATE_FORMAT_TYPE1);
        //获取门禁信息
        String[] entrances = StringHandlerUtil.splitString(vo.getMainDeviceUnique()+","+vo.getSubDeviceUnique());
        DeviceAuthTempPageVO<EntranceTempAuthPageVO> page = new DeviceAuthTempPageVO<>();
        page.setPage(Integer.valueOf(vo.getPage()));
        List<EntranceTempAuthPageVO> list = new ArrayList<>();
        int currentPage = StringUtils.isNotBlank(vo.getPage()) ? Integer.valueOf(vo.getPage()) : 1;
        int pageSize = StringUtils.isNotBlank(vo.getPageSize()) ? Integer.valueOf(vo.getPageSize()) : 20;
        int startPage = (currentPage-1)*pageSize;
        int endPage = (currentPage-1)*pageSize+pageSize;
        int count = 1;
        int haveNext = 0;
        int currentCount = 0;
        List<CloudEntranceVO> entranceList = iDeviceEntranceInfoDao.getEntranceAddressInfo(entrances);
        for(CloudEntranceVO entrance : entranceList) {
            EntranceTempAuthPageVO entranceVO = new EntranceTempAuthPageVO();
            entranceVO.setDoorNum(StringHandlerUtil.autlSupply(4, StringHandlerUtil.getDeviceIdByDeviceUnique(entrance.getMainDeviceUnique()), "0"));
            List<EntranceTempAuthVO> vos = new ArrayList<>();
            //查询门禁地址
            Map<String, Object> address = iCloudEntranceDao.getDeviceAddress(entrance.getMainDeviceUnique());
            List<CloudElevatorVO> elevators;
            if (address != null && (address.get("unitId")!=null || address.get("buildId")!=null)) {
                elevators = iCloudElevatorDao.getDeviceUniquesByEntranceAddress(address);
            }else{
                elevators = new ArrayList<>();
            }
            //获取门禁临时权限
            List<Map<String, Object>> auths = iDeviceEntranceInfoDao.getTempAuthsByAllAuth(Integer.valueOf(StringHandlerUtil.autlSupply(4, StringHandlerUtil.getDeviceIdByDeviceUnique(entrance.getMainDeviceUnique()), "0")), vo.getProjectId());
            for (Map<String, Object> auth : auths) {
                if (count > startPage && count <= endPage) {
                    EntranceTempAuthVO tempVO = new EntranceTempAuthVO();
                    tempVO.setUserId(StringHandlerUtil.getNullOrStringForObject(auth.get("userId")));
                    tempVO.setUserName(StringHandlerUtil.getNullOrStringForObject(auth.get("userName")));
                    tempVO.setIdcardKey(StringHandlerUtil.getNullOrStringForObject(auth.get("idcardKey")));
                    tempVO.setFacePicUrl(StringHandlerUtil.getNullOrStringForObject(auth.get("facePicUrl")));
                    tempVO.setVisitorType(auth.get("visitorType") != null ? Integer.valueOf(auth.get("visitorType").toString()) : null);
                    tempVO.setIsLoss(StringHandlerUtil.getNullOrStringForObject(auth.get("isLoss")));
                    if (entrance.getEntranceCategory().equals(23)) {
                        //获取门禁地址下的电梯
                        if (address != null) {
                            //获取地址下电梯的临时权限
                            Set<String> frontFloor = new HashSet<>();           //正门楼层
                            Set<String> backFloor = new HashSet<>();            //背门楼层
                            for (CloudElevatorVO elevator : elevators) {
                                //获取电梯的授权设备信息
                                List<AppElevatorAuthDTO> elevatorAuths = iCloudElevatorDao.getFloorAuth(auth.get("userId").toString(),
                                        entrance.getProjectId(), Integer.valueOf(elevator.getDeviceId()));
                                AppElevatorAuthVO tempElevatorAuth = StringHandlerUtil.convertElevatorAuth(elevatorAuths);
                                Optional<AppElevatorInfoVO> eAuth = tempElevatorAuth.getElevatorAuth().stream().filter(temp -> temp.getDeviceId().equals(elevator.getDeviceId())).findFirst();
                                if (eAuth.isPresent()) {
                                    String[] floors = StringHandlerUtil.splitString(eAuth.get().getLiveFloor());
                                    if (floors.length > 0) {
                                        String floorsStr = iCloudElevatorDao.getFloorNumByNaturalFloor(floors, vo.getProjectId() + "1" + eAuth.get().getDeviceId());
                                        floors = StringHandlerUtil.splitString(floorsStr);
                                    }
                                    for (String floor : floors) {
                                        if (elevator.getLiftDoorType() == 1) {
                                            frontFloor.add(floor);
                                        } else {
                                            backFloor.add(floor);
                                        }
                                    }
                                }
                            }
                            tempVO.setFrontFloor(String.join(",", frontFloor));
                            tempVO.setBackFloor(String.join(",", backFloor));
                        }
                    }
                    vos.add(tempVO);
                    currentCount++;
                    haveNext = 0;
                }
                count++;
            }
            //获取访客
            List<DeviceTempVisitorVO> visitors = iDeviceEntranceInfoDao.getVisitors(entrance.getMainDeviceUnique());
            for (DeviceTempVisitorVO visitor : visitors) {
                if (count > startPage && count <= endPage) {
                    EntranceTempAuthVO tempVO = new EntranceTempAuthVO();
                    BeanUtils.copyProperties(visitor, tempVO);
                    if (entrance.getEntranceCategory().equals(23)) {
                        //查询门禁地址
                        if (address != null) {
                            //获取门禁地址下的电梯
                            if (StringUtils.isNotBlank(visitor.getFrontElevatorAuth())) {
                                Map<String, Object> frontList = JsonUtil.toObject(visitor.getFrontElevatorAuth(), HashMap.class);
                                Set<String> fronts = new HashSet<>();
                                for (String key : frontList.keySet()) {
                                    Optional<CloudElevatorVO> optional = elevators.stream().filter(elevator -> elevator.getDeviceId().equals(key)).findFirst();
                                    if (optional.isPresent()) {
                                        String[] floor = StringHandlerUtil.splitString(frontList.get(key).toString());
                                        if (floor.length > 0) {
                                            String floors = iCloudElevatorDao.getFloorNumByNaturalFloor(floor, entrance.getProjectId() + "1" + optional.get().getDeviceId());
                                            floor = StringHandlerUtil.splitString(floors);
                                        }
                                        for (String f : floor) {
                                            fronts.add(f);
                                        }
                                    }
                                }
                                tempVO.setFrontFloor(String.join(",", fronts));
                            }
                            if (StringUtils.isNotBlank(visitor.getBackElevatorAuth())) {
                                Map<String, Object> backList = JsonUtil.toObject(visitor.getBackElevatorAuth(), HashMap.class);
                                Set<String> backs = new HashSet<>();
                                for (String key : backList.keySet()) {
                                    Optional<CloudElevatorVO> optional = elevators.stream().filter(elevator -> elevator.getDeviceId().equals(key)).findFirst();
                                    if (optional.isPresent()) {
                                        String[] floor = StringHandlerUtil.splitString(backList.get(key).toString());
                                        if (floor.length > 0) {
                                            String floors = iCloudElevatorDao.getFloorNumByNaturalFloor(floor, entrance.getProjectId() + "1" + optional.get().getDeviceId());
                                            floor = StringHandlerUtil.splitString(floors);
                                        }
                                        for (String f : floor) {
                                            backs.add(f);
                                        }
                                    }
                                }
                                tempVO.setBackFloor(String.join(",", backs));
                            }
                        }
                    }
                    vos.add(tempVO);
                    currentCount++;
                    haveNext = 0;
                }
                count++;
            }
            entranceVO.setDeviceAuthArr(vos);
            list.add(entranceVO);
        }
        page.setDeviceAuthArr(list);
        page.setTotal(count-1);
        if(page.getTotal()<=endPage){
            haveNext = 0;
        }else{
            haveNext = 1;
        }
        page.setPage(currentPage);
        page.setCurrentTotal(currentCount);
        page.setHaveNext(haveNext);
        String endDate = DateUtil.fomatDate(new Date(),DateUtil.DATE_FORMAT_TYPE1);
        Map<String,Object> map = DateUtil.reckonDate(endDate,date);
        System.out.println("【耗时】:"+map.get("s").toString());
        return page;
    }

    /**
     * <desc>
     *      生成人脸指令
     * </desc>
     *
     * @param deviceUnique  人脸识别仪编号
     * @param userId   用户编号
     * @return
     * @author Qiang.S
     * @createDate 2019/12/24
     */
    @Override
    public void createUserInstruct(String deviceUnique,String userId) throws Exception {
        JSONObject json = new JSONObject();
        json.put("userId", userId);
        json.put("projectId", StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique));
        // 云门禁
        List<DeviceBusinessEntranceChangeLogPO> changeEntranceLogPOS = new ArrayList<>();
        changeEntranceLogPOS.add(new DeviceBusinessEntranceChangeLogPO(CloudEntranceChangeBusinessEnum.PUSH_USER_PROJECT, json, StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique)));

        JSONObject dataJs = new JSONObject();
        dataJs.put("data", changeEntranceLogPOS);
        //发送云门禁指令
        messageSender.send(
                RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                JSON.toJSONString(dataJs),
                RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
        );
    }

    /**
     * <desc>
     *      获取门禁人脸识别配置信息
     * </desc>
     *
     * @param sn
     * @return
     * @author Jiaqi.X
     * @createDate 2018/05/21
     */
    public CloudTalkFaceApplyInfoVO getDoorFaceInfo(String sn){
        CloudTalkFaceApplyInfoVO vo = iCloudIntercomDeviceServiceDao.pullDeviceInfo(StringHandlerUtil.getProjectIdBySn(sn));
        if(vo!=null) {
            vo.setGroupId("itlong");
            if ("0".equals(vo.getLivenessControl())) {vo.setLivenessControl("LOW");}
            if ("1".equals(vo.getLivenessControl())) {vo.setLivenessControl("NORMAL");}
            if ("2".equals(vo.getLivenessControl())) {vo.setLivenessControl("HIGH");}
            if ("3".equals(vo.getLivenessControl())) {vo.setLivenessControl("NONE");}
            vo.setQualityControl("NONE");
            if(iCloudIntercomDeviceServiceDao.getFaceStatus(StringHandlerUtil.getProjectIdBySn(sn)).equals("1")){
                vo.setEnable(true);
            }else{
                vo.setEnable(false);
            }
        }else{
            vo = new CloudTalkFaceApplyInfoVO();
            vo.setEnable(false);
        }
        return vo;
    }

    /**
     * <desc>
     * 根据sn 获取状态
     * </desc>
     *
     * @param sn@return
     * @author caoshuai
     * @createDate 2020/12/27 11:44
     */
    @Override
    public String getStatusBySn(String sn) {
        return iDeviceEntranceInfoDao.getStatusBySn(sn);
    }

}
